home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 June / CHIP Haziran 2001.iso / prog / haziran / 19 / setup.exe / data.z / pci_diag_lib.pas < prev    next >
Pascal/Delphi Source File  |  2001-04-11  |  10KB  |  352 lines

  1. {
  2.  ----------------------------------------------------------------
  3.   File - PCI_DIAG_LIB.PAS
  4.  
  5.   Utility functions for printing card information,
  6.   detecting PCI cards, and accessing PCI configuration
  7.   registers.
  8.  ----------------------------------------------------------------
  9. }    
  10.  
  11. unit PCI_diag_lib;
  12.  
  13. interface
  14.  
  15. uses
  16.     Windows,
  17.     SysUtils,
  18.     windrvr,
  19.     print_struct;
  20.  
  21. type FIELDS_ARRAY = record
  22.         name : PCHAR;
  23.         dwOffset : DWORD;
  24.         dwBytes : DWORD;
  25.         dwVal : DWORD;
  26.      end;
  27.  
  28. var
  29.     line : string[255];            { input of command from user }
  30.  
  31. function PCI_Get_WD_handle(phWD : PHANDLE) : BOOLEAN;
  32. procedure PCI_Print_card_info(pciSlot : WD_PCI_SLOT);
  33. procedure PCI_Print_all_cards_info;
  34. procedure PCI_EditConfigReg(pciSlot : WD_PCI_SLOT);
  35. function PCI_ChooseCard(ppciSlot : PWD_PCI_SLOT) : BOOLEAN;
  36.  
  37.  
  38. implementation
  39.  
  40.  
  41. function PCI_Get_WD_handle(phWD : PHANDLE) : BOOLEAN;
  42. var
  43.     ver : SWD_VERSION;
  44.  
  45. begin
  46.     phWD^ := INVALID_HANDLE_VALUE;
  47.     phWD^ := WD_Open();
  48.  
  49.     { Check whether handle is valid and version OK }
  50.     if phWD^ = INVALID_HANDLE_VALUE
  51.     then
  52.     begin
  53.         Writeln('Cannot open WinDriver device');
  54.         PCI_Get_WD_handle := False;
  55.         Exit;
  56.     end;
  57.  
  58.     FillChar(ver, SizeOf(ver), 0);
  59.     WD_Version(phWD^,ver);
  60.     if ver.dwVer<WD_VER
  61.     then
  62.     begin
  63.         Writeln('Error - incorrect WinDriver version');
  64.         WD_Close(phWD^);
  65.         phWD^ := INVALID_HANDLE_VALUE;
  66.         PCI_Get_WD_handle := False;
  67.     end
  68.     else
  69.         PCI_Get_WD_handle := True;
  70. end;
  71.  
  72. procedure PCI_Print_card_info(pciSlot : WD_PCI_SLOT);
  73. var
  74.     hWD : HANDLE;
  75.     pciCardInfo : WD_PCI_CARD_INFO;
  76.  
  77. begin
  78.     if not PCI_Get_WD_handle (@hWD)
  79.     then
  80.         Exit;
  81.  
  82.     FillChar(pciCardInfo, SizeOf(pciCardInfo), 0);
  83.     pciCardInfo.pciSlot := pciSlot;
  84.     WD_PciGetCardInfo (hWD, pciCardInfo);
  85.  
  86.     WD_CARD_print(@pciCardInfo.Card, '   ');
  87.  
  88.     WD_Close (hWD);
  89. end;
  90.  
  91. procedure PCI_Print_all_cards_info;
  92. var
  93.     hWD : HANDLE;
  94.     i : INTEGER;
  95.     pciScan : WD_PCI_SCAN_CARDS;
  96.     pciSlot : WD_PCI_SLOT;
  97.     pciId : WD_PCI_ID;
  98.     tmp : string[2];
  99.  
  100. begin
  101.     if not PCI_Get_WD_handle (@hWD)
  102.     then
  103.         Exit;
  104.  
  105.     FillChar(pciScan, SizeOf(pciScan), 0);
  106.     pciScan.searchId.dwVendorId := 0;
  107.     pciScan.searchId.dwDeviceId := 0;
  108.  
  109.     Writeln('Pci bus scan.');
  110.     Writeln('');
  111.     WD_PciScanCards (hWD,pciScan);
  112.  
  113.     for i:=1 to pciScan.dwCards do
  114.     begin
  115.         pciId := pciScan.cardId[i-1];
  116.         pciSlot := pciScan.cardSlot[i-1];
  117.         Writeln('Bus ', pciSlot.dwBus, ' Slot ', pciSlot.dwSlot, ' Function ', pciSlot.dwFunction,
  118.             ' VendorID $', IntToHex(pciId.dwVendorId, 4), ' DeviceID $', IntToHex(pciId.dwDeviceId, 4));
  119.         PCI_Print_card_info(pciSlot);
  120.         Writeln('Press Enter to continue to next slot');
  121.         Readln(tmp);
  122.     end;
  123.     WD_Close (hWD);
  124. end;
  125.  
  126. function PCI_ReadBytes(hWD : HANDLE; pciSlot : WD_PCI_SLOT; dwOffset : DWORD; dwBytes : DWORD) : DWORD;
  127. var
  128.     pciCnf : WD_PCI_CONFIG_DUMP;
  129.     dwVal : DWORD;
  130.     dwMask : DWORD;
  131.     dwDwordOffset : DWORD;
  132.  
  133. begin
  134.     dwVal := 0;
  135.     dwDwordOffset := dwOffset mod 4;
  136.     FillChar(pciCnf, SizeOf(pciCnf), 0);
  137.     pciCnf.pciSlot := pciSlot;
  138.     pciCnf.pBuffer := @dwVal;
  139.     pciCnf.dwOffset := dwOffset;
  140.     pciCnf.dwOffset := pciCnf.dwOffset - dwDwordOffset;
  141.     pciCnf.dwBytes := 4;
  142.     pciCnf.fIsRead := 1;
  143.     WD_PciConfigDump(hWD,pciCnf);
  144.  
  145.     dwVal := dwVal shr (dwDwordOffset*8);
  146.     case dwBytes of
  147.     1:
  148.         dwMask := $ff;
  149.     2:
  150.         dwMask := $ffff;
  151.     3:
  152.         dwMask := $ffffff;
  153.     4:
  154.         dwMask := $ffffffff;
  155.     end;
  156.     dwVal := dwVal and dwMask;
  157.     PCI_ReadBytes := dwVal;
  158. end;
  159.  
  160. procedure PCI_WriteBytes(hWD : HANDLE; pciSlot : WD_PCI_SLOT; dwOffset : DWORD; dwBytes : DWORD; dwData : DWORD);
  161. var
  162.     pciCnf : WD_PCI_CONFIG_DUMP;
  163.     dwVal : DWORD;
  164.     dwMask : DWORD;
  165.     dwDwordOffset : DWORD;
  166.  
  167. begin
  168.     dwVal := 0;
  169.     dwDwordOffset := dwOffset mod 4;
  170.     FillChar(pciCnf, SizeOf(pciCnf), 0);
  171.     pciCnf.pciSlot := pciSlot;
  172.     pciCnf.pBuffer := @dwVal;
  173.     pciCnf.dwOffset := dwOffset;
  174.     pciCnf.dwOffset := pciCnf.dwOffset - dwDwordOffset;
  175.     pciCnf.dwBytes := 4;
  176.     pciCnf.fIsRead := 1;
  177.     WD_PciConfigDump(hWD,pciCnf);
  178.  
  179.     case dwBytes of
  180.     1:
  181.         dwMask := $ff;
  182.     2:
  183.         dwMask := $ffff;
  184.     3:
  185.         dwMask := $ffffff;
  186.     4:
  187.         dwMask := $ffffffff;
  188.     end;
  189.     dwVal := dwVal and (not (dwMask shl (dwDwordOffset*8)));
  190.     dwVal := dwVal or ((dwMask and dwData) shl (dwDwordOffset*8));
  191.  
  192.     pciCnf.fIsRead := 0;
  193.     WD_PciConfigDump(hWD,pciCnf);
  194. end;
  195.  
  196. procedure PCI_EditConfigReg(pciSlot : WD_PCI_SLOT);
  197. var
  198.     hWD : HANDLE;
  199.     fields : array [0..29] of FIELDS_ARRAY;
  200.     i, cmd : INTEGER;
  201.     dwVal : DWORD;
  202.  
  203. begin
  204.     if not PCI_Get_WD_handle (@hWD)
  205.     then
  206.         Exit;
  207.  
  208.     i := 0;
  209.     fields[i].name := 'VID'; fields[i].dwOffset := $0; fields[i].dwBytes := 2; i:=i+1;
  210.     fields[i].name := 'DID'; fields[i].dwOffset := $2; fields[i].dwBytes := 2; i:=i+1;
  211.     fields[i].name := 'CMD'; fields[i].dwOffset := $4; fields[i].dwBytes := 2; i:=i+1;
  212.     fields[i].name := 'STS'; fields[i].dwOffset := $6; fields[i].dwBytes := 2; i:=i+1;
  213.     fields[i].name := 'RID'; fields[i].dwOffset := $8; fields[i].dwBytes := 1; i:=i+1;
  214.     fields[i].name := 'CLCD'; fields[i].dwOffset := $9; fields[i].dwBytes := 3; i:=i+1;
  215.     fields[i].name := 'CALN'; fields[i].dwOffset := $c; fields[i].dwBytes := 1; i:=i+1;
  216.     fields[i].name := 'LAT'; fields[i].dwOffset := $d; fields[i].dwBytes := 1; i:=i+1;
  217.     fields[i].name := 'HDR'; fields[i].dwOffset := $e; fields[i].dwBytes := 1; i:=i+1;
  218.     fields[i].name := 'BIST'; fields[i].dwOffset := $f; fields[i].dwBytes := 1; i:=i+1;
  219.     fields[i].name := 'BADDR0'; fields[i].dwOffset := $10; fields[i].dwBytes := 4; i:=i+1;
  220.     fields[i].name := 'BADDR1'; fields[i].dwOffset := $14; fields[i].dwBytes := 4; i:=i+1;
  221.     fields[i].name := 'BADDR2'; fields[i].dwOffset := $18; fields[i].dwBytes := 4; i:=i+1;
  222.     fields[i].name := 'BADDR3'; fields[i].dwOffset := $1c; fields[i].dwBytes := 4; i:=i+1;
  223.     fields[i].name := 'BADDR4'; fields[i].dwOffset := $20; fields[i].dwBytes := 4; i:=i+1;
  224.     fields[i].name := 'BADDR5'; fields[i].dwOffset := $24; fields[i].dwBytes := 4; i:=i+1;
  225.     fields[i].name := 'EXROM'; fields[i].dwOffset := $30; fields[i].dwBytes := 4; i:=i+1;
  226.     fields[i].name := 'INTLN'; fields[i].dwOffset := $3c; fields[i].dwBytes := 1; i:=i+1;
  227.     fields[i].name := 'INTPIN'; fields[i].dwOffset := $3d; fields[i].dwBytes := 1; i:=i+1;
  228.     fields[i].name := 'MINGNT'; fields[i].dwOffset := $3e; fields[i].dwBytes := 1; i:=i+1;
  229.     fields[i].name := 'MAXLAT'; fields[i].dwOffset := $3f; fields[i].dwBytes := 1; i:=i+1;
  230.     repeat
  231.     begin
  232.         Writeln('');
  233.         Writeln('Edit PCI configuration registers');
  234.         Writeln('--------------------------------');
  235.         for i:=0 to 20 do
  236.         begin
  237.             fields[i].dwVal := PCI_ReadBytes(hWD, pciSlot, fields[i].dwOffset, fields[i].dwBytes);
  238.         Writeln(i+1, '. ', fields[i].name, ' : ', IntToHex(fields[i].dwVal, 8));
  239.         end;
  240.         Writeln('99. Back to main menu');
  241.         Write('Choose register to write to, or 99 to exit: ');
  242.         cmd := 0;
  243.         Readln(line);
  244.         cmd := StrToInt(line);
  245.         if (cmd>=1) and (cmd<=21)
  246.         then
  247.         begin
  248.             i := cmd-1;
  249.             Write('Enter value (Hex) to write to ', fields[i].name, ' register (or <X> to cancel): ');
  250.             Readln(line);
  251.             line := UpperCase(line);
  252.             if line[1]<>'X'
  253.             then
  254.         begin
  255.                 dwVal := 0;
  256.                 dwVal := HexToInt(line);
  257.             if ((dwVal > $ff) and (fields[i].dwBytes = 1))
  258.                     or ((dwVal > $ffff) and (fields[i].dwBytes = 2))
  259.             or ((dwVal > $ffffff) and (fields[i].dwBytes = 3))
  260.                 then
  261.                     Writeln('Error: value to big for register')
  262.                 else
  263.                     PCI_WriteBytes(hWD, pciSlot, fields[i].dwOffset, fields[i].dwBytes, dwVal);
  264.             end;
  265.         end;
  266.     end;
  267.     until cmd=99;
  268.  
  269.     WD_Close (hWD);
  270. end;
  271.  
  272. function PCI_ChooseCard(ppciSlot : PWD_PCI_SLOT) : BOOLEAN;
  273. var
  274.     fHasCard : BOOLEAN;
  275.     pciScan : WD_PCI_SCAN_CARDS;
  276.     dwVendorID, dwDeviceID : DWORD;
  277.     hWD : HANDLE;
  278.     i : DWORD;
  279.  
  280. begin
  281.     if not PCI_Get_WD_handle (@hWD)
  282.     then
  283.     begin
  284.         PCI_ChooseCard := False;
  285.     Exit;
  286.     end;
  287.  
  288.     fHasCard := False;
  289.  
  290.     while not fHasCard do
  291.     begin
  292.         dwVendorID := 0;
  293.         Write('Enter VendorID: ');
  294.         Readln(line);
  295.         dwVendorID := HexToInt(line);
  296.         if dwVendorID = 0
  297.         then
  298.             Break;
  299.  
  300.         Write('Enter DeviceID: ');
  301.         Readln(line);
  302.         dwDeviceID := HexToInt(line);
  303.  
  304.         FillChar(pciScan, SizeOf(pciScan), 0);
  305.         pciScan.searchId.dwVendorId := dwVendorID;
  306.         pciScan.searchId.dwDeviceId := dwDeviceID;
  307.         WD_PciScanCards (hWD, pciScan);
  308.         if pciScan.dwCards = 0             { One card at least must be found }
  309.         then
  310.             Writeln('Error - cannot find PCI card')
  311.         else
  312.             if pciScan.dwCards = 1
  313.         then
  314.         begin
  315.             ppciSlot^ := pciScan.cardSlot[0];
  316.             fHasCard := True;
  317.         end
  318.         else
  319.         begin
  320.             Writeln('Found ', pciScan.dwCards, ' matching PCI cards');
  321.             Write('Select card (1-', pciScan.dwCards, '): ');
  322.             i := 0;
  323.             Readln(line);
  324.             i := StrToInt(line);
  325.             if (i>=1) and (i <=pciScan.dwCards)
  326.             then
  327.             begin
  328.                 ppciSlot^ := pciScan.cardSlot[i-1];
  329.                 fHasCard := True;
  330.             end
  331.             else
  332.                 Writeln('Choice out of range');
  333.         end;
  334.         if not fHasCard
  335.     then
  336.         begin
  337.             Write('Do you want to try a different VendorID/DeviceID? ');
  338.             Readln(line);
  339.         line := UpperCase(line);
  340.         if line[1] <> 'Y'
  341.         then
  342.                 Break;
  343.         end;
  344.     end;
  345.  
  346.     WD_Close (hWD);
  347.  
  348.     PCI_ChooseCard := fHasCard;
  349. end;
  350.  
  351. end.
  352.